﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using ST.Buz.Base.Entity;
using ST.Buz.Base.Enums;
using ST.Buz.Base.ViewModel;
using ST.Buz.Service;
using ST.Common.Data;
using ST.Common.Util;
using ST.Common.Util.Model;
using ST.Common.Util.Mvc;
using ST.Common.Util.Text;
using System;
using System.IO;
using System.Net;

namespace ST.Buz.Web.Controllers
{
	[Route("sys/attachment")]
	public class Sys_AttachmentController : MyBaseController
	{
		/// <summary>
		/// 上传文件大小限制
		/// </summary>
		private static int MAX_FILE_SIZE = 10485760;//10M

		private readonly IServiceSysAttachment service;
		//private readonly IServiceProdSku serviceProdSku;

		public Sys_AttachmentController(
			IServiceSysAttachment _service,
			//IServiceProdSku _serviceProdSku,
			ILogger<Sys_AttachmentController> _logger) : base(_logger)
		{
			service = _service;
			//serviceProdSku = _serviceProdSku;
		}

		private VMS_Sys_Attachment GetSearchModelFromJson(JObject paras)
		{
			var vm = new VMS_Sys_Attachment();
			vm.pnum = TextHelper.GetInt(paras, "pnum");
			vm.psize = TextHelper.GetInt(paras, "psize");
			vm.sortorder = TextHelper.GetString(paras, "sortorder");

			vm.infoid = TextHelper.GetInt(paras, "infoid");
			vm.tblid = TextHelper.GetInt(paras, "tblid");
			vm.date_s = TextHelper.GetDateTimeStart(paras, "date_s");
			vm.date_e = TextHelper.GetDateTimeEnd(paras, "date_e");
			vm.ids = TextHelper.GetInts(paras, "ids");
			return vm;
		}

		private VMS_Sys_Attachment GetSearchModelFromGetRequest()
		{
			var vm = new VMS_Sys_Attachment();
			vm.pnum = TextHelper.GetInt(Request.Query["pnum"]);
			vm.psize = TextHelper.GetInt(Request.Query["psize"]);
			vm.sortorder = TextHelper.GetString(Request.Query["sortorder"]);

			vm.infoid = TextHelper.GetInt(Request.Query["infoid"]);
			vm.tblid = TextHelper.GetInt(Request.Query["tblid"]);
			vm.date_s = TextHelper.GetDateTimeStart(Request.Query["date_s"]);
			vm.date_e = TextHelper.GetDateTimeEnd(Request.Query["date_e"]);
			vm.ids = TextHelper.GetInts(Request.Query["ids"]);
			return vm;
		}

		private VMS_Sys_Attachment GetSearchModelFromPostRequest()
		{
			var vm = new VMS_Sys_Attachment();
			vm.pnum = TextHelper.GetInt(Request.Form["pnum"]);
			vm.psize = TextHelper.GetInt(Request.Form["psize"]);
			vm.sortorder = TextHelper.GetString(Request.Form["sortorder"]);

			vm.infoid = TextHelper.GetInt(Request.Form["infoid"]);
			vm.tblid = TextHelper.GetInt(Request.Form["tblid"]);
			vm.date_s = TextHelper.GetDateTimeStart(Request.Form["date_s"]);
			vm.date_e = TextHelper.GetDateTimeEnd(Request.Form["date_e"]);
			vm.ids = TextHelper.GetInts(Request.Form["ids[]"]);
			return vm;
		}

		#region 基础方法
		[HttpPost("search")]
		public IActionResult Search([FromBody] JObject paras)
		{
			try
			{
				UserSession sessionCurrent = GetSessionFromRequest();
				var searchModel = GetSearchModelFromJson(paras);
				PageData pageData = service.GetPageList(searchModel);

				return new JsonResultPage(pageData);
			}
			catch (AuthException ex)
			{
				return new JsonResultBase(false, ex.Message, (int)HttpStatusCode.Unauthorized);
			}
			catch (BuzException ex)
			{
				return new JsonResultBase(false, ex.Message);
			}
			catch (ArgumentException ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				return new JsonResultBase(false, ex.Message, (int)HttpStatusCode.BadRequest);
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				return new JsonResultBase(false, "请求出错", (int)HttpStatusCode.InternalServerError);
			}
		}

		[HttpPost("count")]
		public IActionResult Count([FromBody] JObject paras)
		{
			try
			{
				UserSession sessionCurrent = GetSessionFromRequest();
				var searchModel = GetSearchModelFromJson(paras);
				var result = service.GetCount(searchModel);

				return new JsonResultBase(result);
			}
			catch (AuthException ex)
			{
				return new JsonResultBase(false, ex.Message, (int)HttpStatusCode.Unauthorized);
			}
			catch (BuzException ex)
			{
				return new JsonResultBase(false, ex.Message);
			}
			catch (ArgumentException ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				return new JsonResultBase(false, ex.Message, (int)HttpStatusCode.BadRequest);
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				return new JsonResultBase(false, "请求出错", (int)HttpStatusCode.InternalServerError);
			}
		}

		[HttpPost("upload")]
		public ActionResult Upload()
		{
			//Response.Headers.Add("Access-Control-Allow-Origin", "*");

			string callback = Request.Form["callback"];
			try
			{
				string fileType = Request.Form["type"];
				string[] validExtensions = null;
				switch (fileType)
				{
					case "image":
						validExtensions = new string[] { ".jpg", ".jpeg", ".bmp", ".png", ".gif" };
						break;
					case "doc":
						validExtensions = new string[] { ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".wps", ".pdf" };
						break;
					case "file":
						validExtensions = new string[] { ".7z", ".zip", ".rar" };
						break;
					default:
						validExtensions = new string[] { ".jpg", ".jpeg", ".bmp", ".png", ".gif", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".wps", ".pdf", ".7z", ".zip", ".rar" };
						break;
				}
				if (Request.Form.Files == null || Request.Form.Files.Count == 0)
				{
					throw new BuzException("请选择要上传的文件");
				}
				IFormFile file = Request.Form.Files[0];
				if (file.Length == 0)
				{
					throw new BuzException("不能上传空文件");
				}
				string fileExt = Path.GetExtension(file.FileName);
				if (Array.IndexOf(validExtensions, fileExt) < 0)
				{
					throw new BuzException("不支持该文件格式");
				}
				if (file.Length > MAX_FILE_SIZE)
				{
					throw new BuzException("文件大小超出限制（" + MAX_FILE_SIZE + "）");
				}
				UserSession userSession = GetSessionFromRequest();

				string fileName = IDGenerator.NextRand32(userSession.SessionType, userSession.SessionID) + fileExt;
				string fileUrl = "/upload/" + fileName;
				string fileDir = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/upload");
				if (!Directory.Exists(fileDir))
				{
					Directory.CreateDirectory(fileDir);
				}
				string filePath = Path.Combine(fileDir, fileName);
				using (FileStream fs = new FileStream(filePath, FileMode.CreateNew))
				{
					file.CopyTo(fs);
				}

				int tblID = TextHelper.GetInt(Request.Form["tblid"]);
				int infoID = TextHelper.GetInt(Request.Form["infoid"]);
				Sys_Attachment model = new Sys_Attachment
				{
					AddDate = DateTime.Now,
					AddManID = userSession.UserID,
					AddManName = userSession.UserName,
					FileUrl = fileUrl,
					FileName = file.FileName,
					FileSize = (int)file.Length,
					SrcName = file.FileName,
					TableID = tblID,
					InfoID = infoID
				};
				service.Add(model);

				SysAttachmentDetail info = new SysAttachmentDetail();
				//info.url = fileUrl;
				info.ID = model.ID;
				info.url = HttpContextHelper.GetRequestDomainBase(Request) + fileUrl;
				info.size = (int)file.Length;
				info.title = file.FileName;
				info.type = fileType;
				info.infoid = infoID;
				info.tblid = tblID;
				if (string.IsNullOrEmpty(callback))
				{
					JsonResultBase ret = new JsonResultBase(info);
					ret.StatusCode = (int)HttpStatusCode.Created;
					return ret;
				}
				else
				{
					return Content(callback + "(" + Json(info) + ")");
				}
			}
			catch (AuthException ex)
			{
				logger.LogError(ex, "解析请求头部验证信息出错");
				if (string.IsNullOrEmpty(callback))
				{
					return new JsonResultBase(false, ex.Message, (int)HttpStatusCode.Unauthorized);
				}
				else
				{
					ResultData ret = new ResultData(false, ex.Message);
					return Content(callback + "(" + Json(ret) + ")");
				}
			}
			catch (BuzException ex)
			{
				if (string.IsNullOrEmpty(callback))
				{
					return new JsonResultBase(false, ex.Message);
				}
				else
				{
					ResultData ret = new ResultData(false, ex.Message);
					return Content(callback + "(" + Json(ret) + ")");
				}
			}
			catch (Exception ex)
			{
				logger.LogError(ex, "上传文件出错");
				if (string.IsNullOrEmpty(callback))
				{
					return new JsonResultBase(false, "上传失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message), (int)HttpStatusCode.InternalServerError);
				}
				else
				{
					ResultData ret = new ResultData(false, "上传失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
					return Content(callback + "(" + Json(ret) + ")");
				}
			}
		}

		[HttpPost("save")]
		public ActionResult Save()
		{
			try
			{
				if (Request.Form.Files == null || Request.Form.Files.Count == 0)
				{
					throw new BuzException("请选择要上传的文件");
				}
				IFormFile file = Request.Form.Files[0];
				if (file.Length == 0)
				{
					throw new BuzException("不能上传空文件");
				}
				string fileExt = Path.GetExtension(file.FileName);
				if (Array.IndexOf(new string[] { ".jpg", ".jpeg", ".bmp", ".png", ".gif" }, fileExt) < 0)
				{
					throw new BuzException("不支持该文件格式");
				}
				if (file.Length > MAX_FILE_SIZE)
				{
					throw new BuzException("文件大小超出限制（" + MAX_FILE_SIZE + "）");
				}

				UserSession userSession = GetSessionFromRequest();

				string fileName = IDGenerator.NextRand32(userSession.SessionType, userSession.SessionID) + fileExt;
				string fileUrl = "/upload/" + fileName;
				string fileDir = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/upload");
				if (!Directory.Exists(fileDir))
				{
					Directory.CreateDirectory(fileDir);
				}
				string filePath = Path.Combine(fileDir, fileName);
				using (FileStream fs = new FileStream(filePath, FileMode.CreateNew))
				{
					file.CopyTo(fs);
				}

				Sys_Attachment model = new Sys_Attachment
				{
					AddDate = DateTime.Now,
					AddManID = userSession.UserID,
					AddManName = userSession.UserName,
					FileUrl = fileUrl,
					FileName = "",
					FileSize = (int)file.Length,
					SrcName = file.FileName,
					TableID = TextHelper.GetInt(Request.Form["tblid"]),
					InfoID = TextHelper.GetInt(Request.Form["infoid"])
				};
				service.Add(model);

				JsonResultBase ret = new JsonResultBase(model);
				ret.StatusCode = (int)HttpStatusCode.Created;
				return ret;
			}
			catch (BuzException ex)
			{
				return new JsonResultBase(false, ex.Message);
			}
			catch (Exception ex)
			{
				logger.LogError(ex, "新增对象信息出错");
				return new JsonResultBase(false, "上传失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message), (int)HttpStatusCode.InternalServerError);
			}
		}

		[ValidateSession]
		[HttpPost("delete")]
		public JsonResult Delete([FromBody] JObject paras)
		{
			try
			{
				CheckParams();

				UserSession sessionCurrent = GetSessionFromRequest();
				var rowID = TextHelper.GetInt(paras, "id");
				var result = service.Delete(rowID, sessionCurrent, false);

				return new JsonResultBase(result);
			}
			catch (AuthException ex)
			{
				return new JsonResultBase(false, ex.Message, (int)HttpStatusCode.Unauthorized);
			}
			catch (BuzException ex)
			{
				return new JsonResultBase(false, ex.Message);
			}
			catch (ArgumentException ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				return new JsonResultBase(false, ex.Message, (int)HttpStatusCode.BadRequest);
			}
			catch (Exception ex)
			{
				logger.LogError(ex.InnerException ?? ex, ex.Message);
				return new JsonResultBase(false, "删除失败", (int)HttpStatusCode.InternalServerError);
			}
		}

		[HttpPost("upload2bind")]
		public ActionResult UploadToBind()
		{
			string callback = Request.Form["callback"];
			try
			{
				int tblID = TextHelper.GetInt(Request.Form["tblid"]);
				int infoID = TextHelper.GetInt(Request.Form["infoid"]);

				string fileType = "image";
				string[] validExtensions = new string[] { ".jpg", ".jpeg", ".bmp", ".png", ".gif" };
				if (Request.Form.Files == null || Request.Form.Files.Count == 0)
				{
					throw new BuzException("请选择要上传的文件");
				}
				IFormFile file = Request.Form.Files[0];
				if (file.Length == 0)
				{
					throw new BuzException("不能上传空文件");
				}
				string fileExt = Path.GetExtension(file.FileName);
				if (Array.IndexOf(validExtensions, fileExt) < 0)
				{
					throw new BuzException("不支持该文件格式");
				}
				if (file.Length > MAX_FILE_SIZE)
				{
					throw new BuzException("文件大小超出限制（" + MAX_FILE_SIZE + "）");
				}
				UserSession userSession = GetSessionFromRequest();
				string fileName = IDGenerator.NextRand32(userSession.SessionType, userSession.SessionID) + fileExt;
				string fileUrl = "/upload/" + fileName;
				string fileDir = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/upload");
				if (!Directory.Exists(fileDir))
				{
					Directory.CreateDirectory(fileDir);
				}
				string filePath = Path.Combine(fileDir, fileName);
				using (FileStream fs = new FileStream(filePath, FileMode.CreateNew))
				{
					file.CopyTo(fs);
				}

				Sys_Attachment model = new Sys_Attachment
				{
					AddDate = DateTime.Now,
					AddManID = userSession.UserID,
					AddManName = userSession.UserName,
					FileUrl = fileUrl,
					FileName = file.FileName,
					FileSize = (int)file.Length,
					SrcName = file.FileName,
					TableID = tblID,
					InfoID = infoID
				};
				service.Add(model);
				string url = HttpContextHelper.GetRequestDomainBase(Request) + fileUrl;
				switch (tblID)
				{
					//case (int)TableCode.IMS_ProdSku:
					//	var sku = serviceProdSku.Get(infoID);
					//	if (null!=sku)
					//	{
					//		sku.Image = url;
					//		serviceProdSku.Update(sku);
					//	}
					//	break;
					default:
						break;
				}

				SysAttachmentDetail info = new SysAttachmentDetail();
				info.url = url;
				info.size = (int)file.Length;
				info.title = file.FileName;
				info.type = fileType;
				info.infoid = infoID;
				info.tblid = tblID;
				if (string.IsNullOrEmpty(callback))
				{
					JsonResultBase ret = new JsonResultBase(info);
					ret.StatusCode = (int)HttpStatusCode.Created;
					return ret;
				}
				else
				{
					return Content(callback + "(" + Json(info) + ")");
				}
			}
			catch (AuthException ex)
			{
				logger.LogError(ex, "解析请求头部验证信息出错");
				if (string.IsNullOrEmpty(callback))
				{
					return new JsonResultBase(false, ex.Message, (int)HttpStatusCode.Unauthorized);
				}
				else
				{
					ResultData ret = new ResultData(false, ex.Message);
					return Content(callback + "(" + Json(ret) + ")");
				}
			}
			catch (BuzException ex)
			{
				if (string.IsNullOrEmpty(callback))
				{
					return new JsonResultBase(false, ex.Message);
				}
				else
				{
					ResultData ret = new ResultData(false, ex.Message);
					return Content(callback + "(" + Json(ret) + ")");
				}
			}
			catch (Exception ex)
			{
				logger.LogError(ex, "上传文件出错");
				if (string.IsNullOrEmpty(callback))
				{
					return new JsonResultBase(false, "上传失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message), (int)HttpStatusCode.InternalServerError);
				}
				else
				{
					ResultData ret = new ResultData(false, "上传失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
					return Content(callback + "(" + Json(ret) + ")");
				}
			}
		}
		#endregion

		#region 辅助方法
		private string GetTableName(string tbl)
		{
			if (string.IsNullOrEmpty(tbl))
			{
				return string.Empty;
			}
			int tblID;
			if (int.TryParse(tbl, out tblID))
			{
				return Enum.GetName(typeof(TableCode), tblID);
			}
			return string.Empty;
		}

		private string GetTableName(int tblID)
		{
			return Enum.GetName(typeof(TableCode), tblID);
		}
		#endregion
	}
}